package lib;


import interfaces.Cell;
import interfaces.ColorDisplay;
import interfaces.ImageDisplay;
import interfaces.Display;
import interfaces.World;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.util.ArrayList;

import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
/**
* The UI of the world to show the living lives. It could contain multiple
* worlds
*/
public class WorldUI extends JFrame{
	
    /*Constructor that init the world with a certain dimension, the number 
    * of worlds will show in the UI
    */
	public WorldUI(ArrayList<World> worlds, int row, int col) {	
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setExtendedState(JFrame.MAXIMIZED_BOTH);
		setTitle("World"); 
		setLocationRelativeTo(null);

        /*The world will have a grid format*/
		setLayout(new GridLayout(row,col));
		
        /*Loop throught all the worlds passed by the user and create UI for
        each of them */
		JPanel[] panels = new JPanel[worlds.size()];
		int worldDimX;
		int worldDimY;
		
		/*initialize the world*/
		for(int i = 0; i < worlds.size(); i++){
	
			World w = worlds.get(i);
			worldDimX = w.getDimension();
			worldDimY = w.is2D() ? w.getDimension() : 1;
			
			JPanel panel = new JPanel();
			panels[i] = panel;
			
            /*each world will be grid layout*/

			panel.setLayout(new GridLayout(worldDimX,worldDimY));
			panel.setBorder(BorderFactory.createEmptyBorder(2,2,2,2));
			panel.setBackground(Color.WHITE);
			/**
			 * Iterate through the grid of the World, and 
			 * use the hashmap to get the correct representation,
			 * and display the cell.
			 */
			for(int j = 0; j < worldDimX; j++){
				for(int k = 0; k < worldDimY; k++){						
				    JLabel label = new JLabel("");
				    label.setBorder(BorderFactory.createLineBorder(Color.BLACK));		    
				    label.setOpaque(true);			    
				    
				    Cell c = w.getCell(new Location(j,k));
				   
				    /*decide to use color or image to represent the cell*/
				    Display curDisplay = w.get(c.getName());
				    if(curDisplay.isColor())
				    	label.setBackground(((ColorDisplay)curDisplay).getColor());
				    else {
				    	ImageIcon icon = ((ImageDisplay)curDisplay).getImage();					    	
				    	label.setIcon(icon);
				    }
				    panel.add(label);					    
				}
			}	

			// Caculate panel location after showing the JFrame in order to get the right insets (window's title bar).
		    int panelX = (getWidth() - panel.getWidth() - getInsets().left - getInsets().right) / 2;
		    int panelY = ((getHeight() - panel.getHeight() - getInsets().top - getInsets().bottom) / 2);
		    panel.setLocation(panelX, panelY);
			
			add(panel, BorderLayout.CENTER);	
		}
		
		setVisible(true);
					

		/* The following loop applies the transform method to every Cell, and
		 * continually updates the display every second, until the window is 
		 * closed.
		 */
		while(true){
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			
			for(int i = 0; i < worlds.size(); i++){
				JPanel panel = panels[i];
				World w = worlds.get(i);
				worldDimX = w.getDimension();
				worldDimY = w.is2D() ? w.getDimension() : 1;w.run();
				
				worlds.set(i,w);
				panel.removeAll();
				
				for(int j = 0; j < worldDimX; j++){
					for(int k = 0; k < worldDimY; k++){						
					    JLabel label = new JLabel("");
					    label.setBorder(BorderFactory.createLineBorder(Color.BLACK));		    
					    label.setOpaque(true);			    
					    
					    Cell c = w.getCell(new Location(j,k));		
					    
					    Display curDisplay = w.get(c.getName());
					    if(curDisplay.isColor())
					    	label.setBackground(((ColorDisplay)curDisplay).getColor());
					    else{
					    	ImageIcon icon = ((ImageDisplay)curDisplay).getImage();					    	
					    	label.setIcon(icon);
					    }
					    panel.add(label);
					}
				}
				
				panels[i] = panel;							
			}	
			for(JPanel p : panels)
				p.revalidate();
			repaint();
			
		}
			
	}
	

}
